package com.yuhuihui.common.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.lang.reflect.Method;

/**
 * 断点工具类
 *
 * @author yuhh
 * @date 2022-10-10 15:20:07
 */
public final class AspectUtil {

    /** logger */
    private static final Logger logger = LoggerFactory.getLogger(AspectUtil.class);

    /**
     * 获取切点的方法
     *
     * @param point 切点
     * @return {@link Method } 切点的方法
     * @author yuhh
     * @date 2021-06-28 13:53:55
     */
    public static Method getMethod(ProceedingJoinPoint point){
        // 获取该切点的对象
        Object thisClass = point.getTarget();
        // 获取该切点的方法名
        String methodName = point.getSignature().getName();
        Method method = null;
        try {
            // 根据方法名和参数类型获取对应的方法
            method = thisClass.getClass().getMethod(methodName, getParameterTypes(point.getArgs()));
        } catch (NoSuchMethodException e) {
            logger.error("[{}].[{}]：找不到该方法", thisClass.getClass().getName(), methodName, e);
        } catch (Exception e) {
            logger.error("[{}].[{}]：获取该方法时出现异常", thisClass.getClass().getName(), methodName, e);
        }
        // 获取该方法上的ErrorInfo注解
        assert method != null;
        return method;
    }

    /**
     * 根据参数对象返回参数类型
     *
     * @param parameters 参数对象数组
     * @return {@link Class }<{@link ? }>{@link [] }
     * @author yuhh
     * @date 2021-06-28 13:55:08
     */
    private static Class<?>[] getParameterTypes(Object[] parameters){
        int length = parameters.length;
        Class<?>[] classes = new Class[length];
        for (int i = 0; i < length; i ++){
            classes[i] = classReplace(parameters[i].getClass());
        }
        return classes;
    }

    /**
     * 类型替换
     *
     * @param cls 需要替换的类型
     * @return {@link Class }<{@link ? }>
     * @author yuhh
     * @date 2021-06-28 13:56:44
     */
    private static Class<?> classReplace(Class<?> cls){
        if (cls == Integer.class){
            return int.class;
        }
        if (cls == Long.class){
            return long.class;
        }
        if (MultipartFile.class.isAssignableFrom(cls)){
            return MultipartFile.class;
        }
        return cls;
    }

    private AspectUtil(){}
}
